package com.umeox.ota.data.repository;

import android.app.Application;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import android.content.Context;

import com.umeox.ota.data.db.DatabaseModule;
import com.umeox.ota.data.repository.cache.Cache;
import com.umeox.ota.data.repository.cache.CacheType;
import com.umeox.ota.data.repository.utils.Preconditions;
import com.abupdate.iot_libs.engine.DataManager;
import com.abupdate.iot_libs.engine.otaStatus.OtaStatusMgr;


/**
 * 数据管理层实现类
 */
public class RepositoryManager implements IRepositoryManager {
    private Application mApplication;
    private Cache<String, Object> mRoomDatabaseCache;
    private final Cache.Factory mCacheFactory;
    private DatabaseModule.RoomConfiguration mRoomConfiguration;

    public RepositoryManager(Application application, Cache.Factory cacheFactory, DatabaseModule.RoomConfiguration roomConfiguration) {
        this.mApplication = application;
        this.mCacheFactory = cacheFactory;
        this.mRoomConfiguration = roomConfiguration;
    }

    @Override
    public void clearAllCache() {
        mRoomDatabaseCache.clear();
    }

    @Override
    public <T> T obtainDataManager(Class<T> aClass) {
        if (aClass.isAssignableFrom(OtaStatusMgr.class)) {
            return (T) OtaStatusMgr.getInstance();
        }
        if (aClass.isAssignableFrom(DataManager.class)) {
            return (T) DataManager.getInstance();
        }
        throw new IllegalArgumentException("Unknown DataManager class: " + aClass.getName());
    }

    @Override
    public Context getContext() {
        return this.mApplication;
    }

    @Override
    public <DB extends RoomDatabase> DB obtainRoomDatabase(Class<DB> database, String dbName) {
        if (mRoomDatabaseCache == null) {
            mRoomDatabaseCache = mCacheFactory.build(CacheType.ROOM_DATABASE_CACHE_TYPE);
        }
        Preconditions.checkNotNull(mRoomDatabaseCache, "Cannot return null from a Cache.Factory#build(int) method");
        DB roomDatabase;
        synchronized (mRoomDatabaseCache) {
            roomDatabase = (DB) mRoomDatabaseCache.get(database.getName());
            if (roomDatabase == null) {
                RoomDatabase.Builder builder = Room.databaseBuilder(mApplication, database, dbName);
                //自定义 Room 配置
                if (mRoomConfiguration != null) {
                    mRoomConfiguration.configRoom(mApplication, builder);
                }
                roomDatabase = (DB) builder.build();
                mRoomDatabaseCache.put(database.getName(), roomDatabase);
            }
        }
        return roomDatabase;
    }
}
